package xyz.iguilty.workflow.core.listener;


import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import xyz.iguilty.workflow.constant.ProcessConstants;
import xyz.iguilty.workflow.core.service.AbstractActivity;
import xyz.iguilty.workflow.model.*;
import xyz.iguilty.workflow.utils.ApplicationContextProvider;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;

@Component
public class GlobalTaskCreatedListener extends AbstractFlowableEngineEventListener {

    @Autowired
    private TaskService taskService;

    @Override
    protected void taskCreated(FlowableEngineEntityEvent event) {
        super.taskCreated(event);
        Object entity = event.getEntity();
        //是否是任务实体类
        if (!(entity instanceof TaskEntity)) {
            return;
        }
        TaskEntity taskEntity = (TaskEntity) entity;
        String taskId = taskEntity.getId();
        AbstractActivity activity = ApplicationContextProvider.getBean(taskEntity.getTaskDefinitionKey(), AbstractActivity.class);
        if (activity == null) {
            return;
        }
        Map<String, Object> variables = new HashMap<>();
        //设置业务当前状态
        String statusAfterCreated = activity.getStatusAfterCreated();
        variables.put(ProcessConstants.CURRENT_STATUS,statusAfterCreated);
        //设置处理人
        ActivityContext context = new ActivityContext();
        context.setTaskId(taskId);
        context.setProcessInstanceId(taskEntity.getProcessInstanceId());
        ActorModel currentActors = activity.getCurrentActors(context);
        String currentActorNameChain = "";
        if (currentActors != null) {
            switch (currentActors.actorType){
                case ASSIGNEE:
                    List<SimpleUser> assignees = currentActors.getAssignees();
                    if (!CollectionUtils.isEmpty(assignees)){
                        StringJoiner stringJoiner = new StringJoiner(",");
                        assignees.forEach(assignee->{
                            taskService.setAssignee(taskId,assignee.getUserId());
                            stringJoiner.add(assignee.getDisplayName());
                        });
                        currentActorNameChain = stringJoiner.toString();
                    }
                    break;
                case CANDIDATE_USER:
                    List<SimpleUser> candidateUsers = currentActors.getCandidateUsers();
                    if (!CollectionUtils.isEmpty(candidateUsers)){
                        StringJoiner stringJoiner = new StringJoiner(",");
                        candidateUsers.forEach(candidateUser->{
                            taskService.addCandidateUser(taskId,candidateUser.getUserId());
                            stringJoiner.add(candidateUser.getDisplayName());
                        });
                        currentActorNameChain = stringJoiner.toString();
                    }
                    break;
                case CANDIDATE_GROUP:
                    List<SimpleGroup> candidateGroups = currentActors.getCandidateGroups();
                    if (!CollectionUtils.isEmpty(candidateGroups)){
                        StringJoiner stringJoiner = new StringJoiner(",");
                        candidateGroups.forEach(candidateGroup->{
                            taskService.addCandidateGroup(taskId,candidateGroup.getGroupId());
                            stringJoiner.add(candidateGroup.getDisplayName());
                        });
                        currentActorNameChain = stringJoiner.toString();
                    }
                    break;
            }

        }
        variables.put(ProcessConstants.CURRENT_ACTOR,currentActorNameChain);
        taskService.setVariables(taskId,variables);
    }

}
